#!/bin/sh

# Copyright 2022 Felix Freeman <libsys@hacktivista.org>
#
# This script is licensed under the 'MIT No Attribution' license terms. I don't
# want attribution nor exclusive rights over it, but I'd love that you free your
# software too.

# This is an automated setup for the services on a Debian 11 machine.
#
# Environment variables
#
# - HAWESE_ENV: 'development' or 'production' (default)
# - PROJECTS: space-separated list of projects to install, defaults to
#   'hawese-core hawese-wallet hawese-payment hawese-seeds userland'
# - ENDPOINT: API endpoint, defaults to 'dev.api.hackware.cl'
# - CORS_ENDPOINT: endpoint from which API will be called, usually userland,
#   defaults to 'dev.userland.hackware.cl'
# - WALLET_ADD_FUNDS_URL: Wallet add funds url, defaults to
#   "https://$CORS_ENDPOINT/add-funds"
# - PAYMENT_RETURN_URL: Page to return after a sucessful payment, defaults to
#   "https://$CORS_ENDPOINT/add-funds/verify"
# - CERTBOT_EMAIL: Email to use for certbot certificates on production, defaults
#   to a randomly generated email @mt2015.com
# - XDEBUG_CLIENT_HOST: Host from which XDebug will connect. Defaults to
#   '_gateway.lxd' when using LXD, 'localhost' otherwise.
#
# This scripts use tabs for indentation of script and spaces for indentation of
# generated config files.

export HAWESE_ENV=${HAWESE_ENV:-production}
export PROJECTS=${PROJECTS:-hawese-core hawese-wallet hawese-payment hawese-seeds userland}
export ENDPOINT=${ENDPOINT:-dev.api.hackware.cl}
export CORS_ENDPOINT=${CORS_ENDPOINT:-dev.userland.hackware.cl}
export WALLET_ADD_FUNDS_URL
export PAYMENT_RETURN_URL

apt install -y mariadb-server php-fpm php-curl php-mysql php-xml php-bcmath composer nginx pwgen
test "$HAWESE_ENV" = 'development' && apt install -y php-xdebug git
case "$PROJECTS" in *userland*) apt install -y npm; esac

export DB_NAME=hawese
export DB_USER=hawese
export DB_PASS="$(pwgen -syc -r \' 32)"

mysql -sf << EOF
CREATE DATABASE $DB_NAME;
GRANT ALL PRIVILEGES ON $DB_NAME.* TO $DB_USER IDENTIFIED BY '$DB_PASS';
FLUSH PRIVILEGES;
EOF

test "$HAWESE_ENV" = 'development' && mysql -sf <<- EOF
	CREATE DATABASE hawese_test;
	GRANT ALL PRIVILEGES ON hawese_test.* TO hawese_test IDENTIFIED BY 'hawese_test';
EOF

useradd -m -d /opt/hawese -k /dev/null -s /bin/sh -g www-data hawese

cd /opt/hawese
USER=hawese HOME=/opt/hawese sudo -E -u hawese setup/setup_user.sh

cat << EOF > /etc/php/7.4/fpm/pool.d/$ENDPOINT.conf
[hawese]
user = hawese
group = www-data
listen = /run/php/php7.4-fpm-hawese.sock
listen.owner = www-data
listen.group = www-data
pm = ondemand
pm.max_children = 5
pm.process_idle_timeout = 60s
EOF
service php7.4-fpm restart

cat << EOF > /etc/nginx/conf.d/$ENDPOINT.conf
server {
    listen 80;
    listen [::]:80;
    server_name $ENDPOINT;

    location / { return 301 https://\$host\$request_uri; }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name $ENDPOINT;

    access_log /var/log/nginx/${ENDPOINT}.access.log;
    error_log /var/log/nginx/${ENDPOINT}.error.log;

    root /opt/hawese/public;
    index index.php;

EOF

if [ "$HAWESE_ENV" = 'development' ]; then
	openssl req -x509 -nodes -newkey rsa:4096 -keyout /etc/ssl/private/$ENDPOINT.key -out /etc/ssl/certs/$ENDPOINT.crt -sha256 -days 3650 -subj "/CN=$ENDPOINT"
	cat <<- EOF >> /etc/nginx/conf.d/$ENDPOINT.conf
	    ssl_certificate /etc/ssl/certs/$ENDPOINT.crt;
	    ssl_certificate_key /etc/ssl/private/$ENDPOINT.key;
	EOF

	cat <<- EOF | tee -a /etc/php/7.4/fpm/php.ini | tee -a /etc/php/7.4/cli/php.ini

	[XDebug]
	xdebug.mode = develop,debug
	xdebug.client_host = ${XDEBUG_CLIENT_HOST:-localhost}
	EOF
else
	apt install -y python3-certbot-nginx
	certbot certonly --nginx --agree-tos --email "${CERTBOT_EMAIL:=$(pwgen 12 1)@mt2015.com}" --no-eff-email -d $ENDPOINT

	cat <<- EOF >> /etc/nginx/conf.d/$ENDPOINT.conf
	    # Certbot certificates
	    ssl_certificate /etc/letsencrypt/live/$ENDPOINT/fullchain.pem;
	    ssl_certificate_key /etc/letsencrypt/live/$ENDPOINT/privkey.pem;
	EOF
fi

cat << EOF >> /etc/nginx/conf.d/$ENDPOINT.conf
    location / {
        try_files \$uri \$uri/ /index.php?\$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php7.4-fpm-hawese.sock;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi.conf;
    }
}
EOF

case "$PROJECTS" in *userland*)
	cat <<- EOF > /etc/nginx/conf.d/$CORS_ENDPOINT.conf
	server {
	    listen 80;
	    listen [::]:80;
	    server_name $CORS_ENDPOINT;

	    location / { return 301 https://\$host\$request_uri; }
	}

	server {
	    listen 443 ssl http2;
	    listen [::]:443 ssl http2;
	    server_name $CORS_ENDPOINT;

	    access_log /var/log/nginx/${CORS_ENDPOINT}.access.log;
	    error_log /var/log/nginx/${CORS_ENDPOINT}.error.log;

	    root /opt/hawese/userland/public;
	    index index.html;

	EOF
	if [ "$HAWESE_ENV" = 'development' ]; then
		openssl req -x509 -nodes -newkey rsa:4096 -keyout /etc/ssl/private/$CORS_ENDPOINT.key -out /etc/ssl/certs/$CORS_ENDPOINT.crt -sha256 -days 3650 -subj "/CN=$CORS_ENDPOINT"
		cat <<- EOF >> /etc/nginx/conf.d/$CORS_ENDPOINT.conf
		    ssl_certificate /etc/ssl/certs/$CORS_ENDPOINT.crt;
		    ssl_certificate_key /etc/ssl/private/$CORS_ENDPOINT.key;

		    location / {
		        proxy_pass http://localhost:8080;
		    }
		}
		EOF
	else
		certbot certonly --nginx --agree-tos --email "$CERTBOT_EMAIL" --no-eff-email -d $CORS_ENDPOINT

		cat <<- EOF >> /etc/nginx/conf.d/$CORS_ENDPOINT.conf
		    # Certbot certificates
		    ssl_certificate /etc/letsencrypt/live/$CORS_ENDPOINT/fullchain.pem;
		    ssl_certificate_key /etc/letsencrypt/live/$CORS_ENDPOINT/privkey.pem;
		}
		EOF
	fi

	cat <<- EOF > "/etc/systemd/system/userland.service"
	[Unit]
	Description=HAWESE userland
	After=syslog.target network.target

	[Service]
	Type=simple
	User=hawese
	Group=www-data
	WorkingDirectory=/opt/hawese/userland
	ExecStart=/usr/bin/npm run serve -- --public https://$CORS_ENDPOINT

	SyslogIdentifier=userland

	[Install]
	WantedBy=default.target
	EOF

	systemctl enable --now userland
esac

service nginx reload
